package de.java.shortys.myhome.api.controller;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.tree.DefaultMutableTreeNode;

import de.java.shortys.myhome.api.controller.navigation.NavigationController;
import de.java.shortys.myhome.api.view.SwingModuleView;

public abstract class AbstractSwingModuleController implements IController {

	private AbstractSwingApplicationController applicationController;

	private SwingModuleView view = new SwingModuleView();

	private List<IController> children = new ArrayList<IController>();

	private boolean active;

	private boolean expanded = true;

	public AbstractSwingModuleController(AbstractSwingApplicationController applicationController) {
		setApplicationController(applicationController);
		getView().setTitle(getTitle());
		getView().setDeactivatable(allowDeactivate());
		createListener();
		initialize();
	}

	@Override
	public void activate() {
		if (allowActivate() && !isActive()) {
			applicationController.getView().activate(view);
			active = true;
			onActivate();
		}
	}

	public void add(IController child) {
		children.add(child);
		NavigationController.getInstance().add(child.getId(), child);
		addToTree(child);
	}

	public void addToTree(IController child) {
		DefaultMutableTreeNode parent = view.add(child.getTitle());
		for (IController sub : child.getChildren()) {
			addToTree(sub, parent);
		}
	}

	public void addToTree(IController child, DefaultMutableTreeNode parent) {
		DefaultMutableTreeNode newChild = new DefaultMutableTreeNode(child.getTitle());
		parent.add(newChild);
		for (IController sub : child.getChildren()) {
			addToTree(sub, newChild);
		}
	}

	@Override
	public void collapse() {
		view.collapse();
		expanded = false;
	}

	protected void createListener() {
		getView().addCloseListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				deactivate();
			}
		});
		getView().addExpandListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				if (isExpanded()) {
					collapse();
				} else {
					expand();
				}
			}
		});

		getView().addTreeClickListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent e) {
				String selectedUserObject = view.getSelectedUserObject();
				if (selectedUserObject != null) {
					IController controller = getControllerByTitle(selectedUserObject);
					controller.activate();
				}
			}
		});
	}

	@Override
	public void deactivate() {
		if (allowDeactivate() && isActive()) {
			applicationController.getView().deactivate(view);
			active = false;
			onDeactivate();
		}
	}

	@Override
	public void expand() {
		view.expand();
		expanded = true;
	}

	public AbstractSwingApplicationController getApplicationController() {
		return applicationController;
	}

	@Override
	public List<IController> getChildren() {
		return children;
	}

	public IController getControllerByTitle(String title) {
		return searchController(title, this);
	}

	@Override
	public IController getParent() {
		return null;
	}

	@Override
	public AbstractSwingModuleController getRoot() {
		return this;
	}

	public SwingModuleView getView() {
		return view;
	}

	@Override
	public boolean isActive() {
		return active;
	}

	public boolean isExpanded() {
		return expanded;
	}

	private IController searchController(String title, IController parent) {
		for (IController controller : parent.getChildren()) {
			if (controller.getTitle().equals(title)) {
				return controller;
			}
			searchController(title, controller);
		}

		return null;
	}

	public void setApplicationController(AbstractSwingApplicationController applicationController) {
		this.applicationController = applicationController;
	}

}
